home *** CD-ROM | disk | FTP | other *** search
/ Ambrosia Times / AT_1.1_5.3_DOCMaker.sit / The Ambrosia Times 5.2.rsrc / TEXT_138.txt < prev    next >
Text File  |  1998-09-25  |  6KB  |  99 lines

  1.  
  2. Bitwise Operator
  3. by Matt Slot
  4.  
  5.  
  6. Probably the most important thing a programmer can do to improve his code is to structure it better. It's not
  7. only a matter of convenience, it means faster implementation of new features, simpler debugging, long term
  8. maintainability, and portable code. It requires a bit of forethought, and an awareness of each portion of the
  9. whole project as it's constructed.
  10.  
  11. I'd like to discuss 3 different places to improve the structure of new and revised code: interface,
  12. implementation, and incremental changes.
  13.  
  14. Interface
  15.  
  16. When designing a new application or library, it's important to understand how each portion will interface
  17. with each other. I'm not talking about USER interfaces, but PROGRAMMER interfaces. Each service that an
  18. application uses or provides should be modular -- well-defined requirements and promised features.
  19.  
  20. The infrastructure routines should provide memory, string, and data storage (lists, trees, tables). Additional
  21. "modules" should provide file, database, and network access. The core application will then provide a layer
  22. between the low level services and the actual user interface (if there is one).
  23.  
  24. For many of the well-advertised reasons, object-oriented programming can simplify the programmer
  25. interfaces between various service modules and the application itself. Even without OOP techniques,
  26. modularized code makes it much easier to update, change, or even port such services because it "abstracts"
  27. these services and hides their implementation behind a simplified set of functions.
  28.  
  29. With this method, the library provide a consistent interface to the caller and the programmer is free to modify
  30. or replace the code that actually implements the promised features.
  31.  
  32. Implementation
  33.  
  34. The next suggestion for improving code structure promotes the use of "bottleneck" routines. These routines
  35. perform a narrowly defined service for the caller, such as sending commands over a network or reading an
  36. arbitrary data chunk from disk and dispatching it to the correct handler.
  37.  
  38. The term bottleneck derives from the fact that many functions will call this one particular routine, and this
  39. routine will dispatch the desired behavior to the appropriate implementation. Bottleneck routines are typically
  40. key programmer interfaces to a specific library or functional module, and either consists of the exact sequence
  41. of calls to provide the functionality or they provide a large switch/case statement that dispatches to multiple
  42. handlers.
  43.  
  44. The primary advantage to such routines is that they provide a single access point for a whole suite of related
  45. functionality. For example, what if the programmer wants to track exactly what data is being written to disk
  46. for debugging or just counting bytes. Consider an application that, each time it needs to write to disk, it
  47. opens the file, scans to the right location, writes the data, closes the disk, and checks for errors. It's pretty
  48. hard to debug the file saving code because it's spread all over the application.
  49.  
  50. On the other hand the programmer should write single routine that performs the entire sequence of steps, and
  51. then call the bottleneck each time data needs to be saved to disk. Later, it becomes trivial to set a debugger
  52. breakpoint to trace exactly which data is being written to disk (and from where in the project). It's also the
  53. perfect place to extend functionality, such as a byte counter or an option to save to the system clipboard.
  54.  
  55. Object oriented programmers often have some language support for writing bottleneck functions using
  56. "polymorphism". In the application, a number of classes can provide a "draw" member function that
  57. performs a slight variation of the same drawing functionality appropriate to the desired object. Adding a call
  58. to the draw member of the base class let's that function act as a bottleneck, to provide common drawing
  59. functionality such as coloring the pen or enabling/disabling drawing at a global level.
  60.  
  61. Incremental Changes
  62.  
  63. In the early stages of design and development, the programmer will try to bottleneck the code in as many
  64. places as possible for the reasons indicated above. This is typically planned at a very high level for the key
  65. functional and data structures. On the other hand, there are often many opportunities to improve the structure
  66. of the code as development progresses and more patterns become evident in the code.
  67.  
  68. Invariably, as existing features are fleshed and new features are added, certain elements or functional
  69. sequences tend to be reappear -- especially in "copy and paste" code. As a good rule of thumb, when I find
  70. myself writing basically the same sequence of code for the third time, I step back and try to find a way to
  71. bottleneck the code.
  72.  
  73. As I become aquainted with new library routines or write code to interact with something written by another
  74. programmer, it often turns out that the interface was written in a rather general purpose manner. This is often
  75. fine because there are often different ways or reasons to use a given piece of code, but when I start using that
  76. code I have a specific use or platform in mind.
  77.  
  78. Each time I program to that library's interface, I must write a bit of glue code to convert from my internal data
  79. format to the general purpose parameters that it expects. As my code depends more upon the new library, it
  80. becomes useful to create wrapper functions that simplify the conversion to reduce code bloat and bottleneck
  81. the functionality. Later, for example, if my code were to change it's internal data units or format, it would be
  82. straightforward to revise just the wrappers themselves and not every place they are used.
  83.  
  84. None of these techniques are well-defined rules for success, but they do provide a certain measure of
  85. structure and stability to code. Using descriptive names for the bottleneck and wrapper routines supplement
  86. programmer comments as a way to improve code readability and maintenance. Writing small utility functions
  87. not only aids debugging, but also saves from problems when writing similar code and missing a +1 in a
  88. certain case.
  89.  
  90. Well-structured application software and programmer libraries are often much more usable and stable than
  91. those that sort of accumulate new features without much forethought. It's also a sign that the programmer
  92. intends to maintain the code in the future, and didn't write it as a weekend hack.
  93.  
  94. Matt Slot, Bitwise Operator
  95.  
  96.     
  97.  
  98.  
  99.